import { useWebSocket } from '../hooks/useWebSocket'
import type { WebSocketOptions } from '../hooks/useWebSocket'
import { ref } from 'vue'
import { feedback } from '../feedback'

class WebSocketManager {
    private static instance: WebSocketManager
    private ws: ReturnType<typeof useWebSocket> | null = null
    private token: string | null = null
    private retryCount = 0
    private maxRetries = 5
    private retryInterval = 5000 // 5秒
    private retryTimer: NodeJS.Timeout | null = null

    // 全局消息订阅者
    private subscribers = new Map<string, (data: any) => void>()
    
    // 连接状态
    public isConnected = ref(false)
    
    private constructor() {}

    public static getInstance(): WebSocketManager {
        if (!WebSocketManager.instance) {
            WebSocketManager.instance = new WebSocketManager()
        }
        return WebSocketManager.instance
    }

    // 初始化 WebSocket 连接
    public init(token: string) {
        // 如果token相同且已连接，则不重复初始化
        if (this.token === token && this.isConnected.value) {
            console.log('WebSocketManager: token未变化且已连接，跳过初始化')
            return
        }
        
        console.log('WebSocketManager: 初始化连接')
        feedback.showWSConnecting()
        this.token = token
        this.retryCount = 0
        this.connect()
    }

    // 建立连接
    private connect() {
        console.log('WebSocketManager: 开始连接')
        
        // 如果已经连接或正在连接中，则不重复连接
        if (this.ws) {
            if (this.ws.isConnected.value) {
                console.log('WebSocketManager: 已经连接')
                feedback.showWSConnected()
                return
            }
            // 如果连接存在但未连接，先断开
            console.log('WebSocketManager: 断开现有连接')
            this.ws.disconnect()
            this.ws = null
        }

        // 清除重连定时器
        if (this.retryTimer) {
            console.log('WebSocketManager: 清除重连定时器')
            clearTimeout(this.retryTimer)
            this.retryTimer = null
        }

        if (!this.token) {
            console.warn('WebSocketManager: 无token，无法连接')
            return
        }

        const wsOptions: WebSocketOptions = {
            url: `${import.meta.env.VITE_APP_WS_URL}?token=${this.token}`,
            heartbeat: {
                message: JSON.stringify({ type: 'ping' }),
                interval: 50000
            },
            reconnectConfig: {
                retries: this.maxRetries,
                delay: this.retryInterval
            },
            onMessage: this.handleMessage.bind(this),
            onOpen: () => {
                console.log('WebSocketManager: 连接成功')
                this.isConnected.value = true
                this.retryCount = 0
                feedback.showWSConnected()
            },
            onClose: () => {
                console.log('WebSocketManager: 连接关闭')
                this.isConnected.value = false
                this.handleReconnect()
            },
            onError: (error) => {
                console.log('WebSocketManager: 连接错误')
                this.isConnected.value = false
                this.handleReconnect()
            }
        }

        console.log('WebSocketManager: 创建新连接', wsOptions.url)
        this.ws = useWebSocket(wsOptions)
    }

    // 处理重连
    private handleReconnect() {
        if (this.retryCount >= this.maxRetries) {
            console.log('WebSocketManager: 已达到最大重试次数', this.maxRetries)
            return
        }

        feedback.showWSReconnecting()

        if (this.retryTimer) {
            clearTimeout(this.retryTimer)
            this.retryTimer = null
        }

        this.retryCount++
        console.log('WebSocketManager: 准备第', this.retryCount, '次重连')

        this.retryTimer = setTimeout(() => {
            if (this.token && !this.isConnected.value) {
                console.log('WebSocketManager: 执行第', this.retryCount, '次重连')
                this.connect()
            } else {
                console.log('WebSocketManager: 已连接或无token，取消重连')
            }
        }, this.retryInterval)
    }

    // 处理接收到的消息
    private handleMessage(data: any) {
        try {
            let message: any;
            
            // 检查数据类型并相应处理
            if (typeof data === 'string') {
                // 检查是否以 'receive message' 开头
                if (data.startsWith('receive message')) {
                    data = data.replace('receive message', '').trim();
                }
                
                try {
                    message = JSON.parse(data);
                } catch (e) {
                    console.log('WebSocketManager: 收到非JSON字符串消息', data);
                    message = data;
                }
            } else if (data instanceof Blob) {
                console.log('WebSocketManager: 收到Blob消息');
                return;
            } else {
                message = data;
            }
            console.log('WebSocketManager: 收到消息' ,message);
            // 检查消息是否为心跳相关
            if (
                message === 'ping' || 
                (typeof message === 'object' && message?.type === 'ping') ||
                (typeof message === 'object' && message?.type === 'ping')
            ) {

                console.log('WebSocketManager: 收到心跳消息' ,message);
                return;
            }

            console.log('WebSocketManager: 收到业务消息', message);
            
            // 遍历所有订阅者，通知消息
            this.subscribers.forEach((callback) => {
                try {
                    callback(message);
                } catch (error) {
                    console.error('WebSocketManager: 订阅者处理消息错误', error);
                }
            });
        } catch (error) {
            console.error('WebSocketManager: 处理消息错误', error);
            console.log('原始消息:', data);
        }
    }

    // 发送消息
    public sendMessage(data: any) {
        if (!this.ws) {
            console.warn('WebSocketManager: WebSocket未初始化')
            return
        }
        console.log('WebSocketManager: 发送消息', data)
        this.ws.sendMessage(data)
    }

    // 订阅消息
    public subscribe(id: string, callback: (data: any) => void) {
        console.log('WebSocketManager: 添加订阅', id)
        this.subscribers.set(id, callback)
    }

    // 取消订阅
    public unsubscribe(id: string) {
        console.log('WebSocketManager: 取消订阅', id)
        this.subscribers.delete(id)
    }

    // 断开连接
    public disconnect() {
        console.log('WebSocketManager: 断开连接')
        if (this.retryTimer) {
            clearTimeout(this.retryTimer)
            this.retryTimer = null
        }

        if (this.ws) {
            this.ws.disconnect()
            this.ws = null
        }
        this.token = null
        this.subscribers.clear()
        this.isConnected.value = false
        this.retryCount = 0
    }

    // 手动重连
    public reconnect() {
        console.log('WebSocketManager: 手动重连')
        this.retryCount = 0
        if (this.token) {
            this.connect()
        } else {
            console.warn('WebSocketManager: 无token，无法重连')
        }
    }

    // 获取重试次数
    public getRetryCount(): number {
        return this.retryCount
    }

    // 获取最大重试次数
    public getMaxRetries(): number {
        return this.maxRetries
    }
}

// 导出单例实例
export const wsManager = WebSocketManager.getInstance()

// 导出类型
export type { WebSocketOptions } 